package com.kiven.action

import com.intellij.openapi.actionSystem.AnAction
import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.actionSystem.PlatformDataKeys
import com.intellij.openapi.project.Project
import com.intellij.openapi.ui.popup.PopupChooserBuilder
import com.intellij.psi.*
import com.intellij.ui.awt.RelativePoint
import com.intellij.ui.components.JBList
import com.kiven.utils.ClassDefinition
import com.kiven.utils.TypeDefinition
import com.kiven.utils.KUtil
import com.ruiyu.utils.showNotify
import java.awt.Dimension
import java.awt.MouseInfo
import java.awt.Toolkit
import java.awt.datatransfer.StringSelection
import java.util.*

/**
 * Created by WangKiven on 2019/9/25.
 */
class DartAppendAction : AnAction() {
    override fun actionPerformed(event: AnActionEvent) {
//        showOkCancelDialog("提示", "hhhhhh", "确定")
        val project = event.getData(PlatformDataKeys.PROJECT) ?: return
//        val comp = event.getData(PlatformDataKeys.EDITOR)

        val psiFile = event.getData(PlatformDataKeys.PSI_FILE) ?: return
//        val virtualFile = event.getData(PlatformDataKeys.VIRTUAL_FILE)
//        val psiElement = event.getData(PlatformDataKeys.PSI_ELEMENT)

        if (psiFile.language.displayName.lowercase(Locale.getDefault()) != "dart") {
            project.showNotify("该文件不是Dart文件")
            return
        }

        // 解析获取类及field
        val cds = arrayListOf<ClassDefinition>()
        psiFile.children.forEach {
            if (it.toString() == "CLASS_DEFINITION") {

                var cd: ClassDefinition? = null

                it.children.forEach {
                    if (it.toString() == "COMPONENT_NAME") {
                        cd = ClassDefinition(it.text, false)
                    } else if (it.toString() == "CLASS_BODY") {
                        it.children.forEach {
                            if (it.toString() == "CLASS_MEMBERS") {
                                it.children.forEach {
                                    if (it.toString() == "VAR_DECLARATION_LIST") {

                                        var fieldType: String? = null
                                        var subFieldType: String? = null
                                        var fieldName: String? = null
                                        var isLate = false// it.children没有late项，只能这么取了，应该是dart插件的原因
                                        var isNullable = false
                                        var isFinal = false
                                        var defaultValue: String? = null//是否有值, null表示没有值，并不表示dart属性是空值。

                                        it.children.forEach {
                                            if (it.toString() == "VAR_ACCESS_DECLARATION") {
                                                // var late final 不在 it.children 里面
                                                isLate =
                                                    it.firstChild.text == "late"// it.children没有late项，只能这么取了，应该是dart插件的原因
                                                isFinal = it.firstChild.text == "final"

                                                println("xxxx ${it} ${it.text} ${it.firstChild.text} ${it.lastChild.text}")
                                                it.children.forEach {
                                                    println("xxxx ${it} ${it.text}")
                                                    if (it.toString() == "TYPE") {
                                                        var tt = it.text
                                                        isNullable = tt.endsWith("?")
                                                        if (isNullable) tt = tt.replace("?", "")

                                                        if (tt.startsWith("List<")) {
                                                            fieldType = "List"
                                                            subFieldType = tt.substring(5, tt.length - 1)
                                                        } else fieldType = tt
                                                    } else if (it.toString() == "COMPONENT_NAME") {
                                                        if (fieldType == null) isNullable = true
                                                        fieldName = it.text
                                                    }
                                                }
                                            } else if (it.toString() == "VAR_INIT") {
                                                it.children.forEach {
                                                    when(it.toString()) {
                                                        "LITERAL_EXPRESSION" -> {
                                                            defaultValue = it.text
                                                        }
                                                        "LIST_LITERAL_EXPRESSION" -> {//list默认值
                                                            defaultValue = it.text
                                                            if (defaultValue?.startsWith("const") != true) {
                                                                defaultValue = "const$defaultValue"
                                                            }
                                                        }
                                                        "SET_OR_MAP_LITERAL_EXPRESSION" -> {//map默认值
                                                            defaultValue = it.text
                                                            if (defaultValue?.startsWith("const") != true) {
                                                                defaultValue = "const$defaultValue"
                                                            }
                                                        }
                                                        "CALL_EXPRESSION" -> {//类默认值
                                                            defaultValue = it.text
                                                        }
                                                        "FUNCTION_EXPRESSION" -> {//方法默认值
                                                            defaultValue = it.text
                                                        }
                                                        else -> {
                                                            defaultValue = it.text
                                                        }
                                                    }
                                                }
                                            }
                                        }



                                        fieldName?.apply {
                                            cd?.addField(
                                                this,
                                                TypeDefinition(
                                                    fieldType ?: "Null",
                                                    subFieldType,
                                                    this,
                                                    isLate,
                                                    isNullable,
                                                    isFinal,
                                                    defaultValue
                                                )
                                            )
                                        }
                                    }
                                }
                            }
                        }
                    }
                }

                if (cd != null)
                    cds.add(cd!!)
            }
            printPsi(it, 1)
        }

        if (cds.size < 1) {
            project.showNotify("该文件没有包含类")
            return
        }

        KUtil.showPopupChoose(
            arrayOf(
                "dart方法 - 创建Dart Entity解析json列表的解析方法",
                "dart方法 - 创建Dart Entity解析json的工厂方法",
                "dart方法 - fromMap()",
                "dart方法 - toMap()",
                "dart方法 - 创建构造方法",
                "dart方法 - late and ?",
            )
        ) { selValue ->
            if (cds.size < 2) {
                copy(project, cds[0], selValue)
            } else {
                KUtil.showPopupChoose(cds.map { it.name }.toTypedArray()) { classIndex ->
                    copy(project, cds[classIndex], selValue)
                }
            }
        }
    }

    private fun printPsi(psi: PsiElement, level: Int) {
        println("$level - $psi - ${psi.text}")
        psi.children.forEach {
            printPsi(it, level + 1)
        }
    }

    private fun copy(project: Project, cd: ClassDefinition, option: Int) {
        if (option == 5) {
            KUtil.showPopupChoose(
                arrayOf(
                    "所有属性添加 late",
                    "所有属性移除 late",
                    "不操作 late"
                )
            ) {
                val allIsLate = if (it == 2) null else it == 0
                KUtil.showPopupChoose(
                    arrayOf(
                        "所有属性可空",
                        "所有属性不可空",
                        "不操作"
                    )
                ) {
                    val allIsNullable = if (it == 2) null else it == 0

                    val ncd = ClassDefinition(cd.name, cd.privateFields)
                    cd.fields.forEach { (s, t) ->
                        ncd.addField(
                            s,
                            TypeDefinition(
                                t.name,
                                t.subtype,
                                t.fieldName,
                                allIsLate ?: t.isLate,
                                allIsNullable ?: t.isNullable,
                                t.isFinal,
                                t.defaultValue
                            )
                        )
                    }
                    val text = ncd._fieldList
                    KUtil.copy(project, text)
                }
            }
            return
        }

        val text = when (option) {
            0 -> cd._jsonListParseFunc
            1 -> cd._jsonFacParesFunc
            2 -> cd._fromMapFunc
            4 -> cd._defaultConstructor
            else -> cd._toMapFunc
        }

        KUtil.copy(project, text)
    }
}